﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.IO;
namespace MyPen
{
    public partial class Form1 : Form
    {
        
        private List<Shape> _listShape = new List<Shape>();
        private Shape _tempShape = null;
        private String _fileName;
        private DrawType _drawtype = DrawType.Line;
        private BufferedGraphicsContext _bufGraphCont = null;
        private BufferedGraphics _bufGraph = null;
        private List<Shape> _listDelShape = new List<Shape>();

        //当前绘制使用的线宽和颜色
        private int _drawWidth = 10;
        private Color _drawColor = Color.Red;
        private double _zoomRation = 1;
        private Size _panelDrawInitSize = new Size(0, 0);

        public DrawType _Drawtype
        {
            get { return _drawtype; }
            set 
            { 
                _drawtype = value;
                if (_drawtype == DrawType.Line)
                {
                    MenuItemLine.CheckState = CheckState.Checked;
                    toolStripButtonLine.Checked = true;
                    MenuItemRect.CheckState = CheckState.Unchecked;
                    toolStripButtonRect.Checked = false;
                    MenuItemCircle.CheckState = CheckState.Unchecked;
                    toolStripButtonCircle.Checked = false;
                    MenuItemSketch.CheckState = CheckState.Unchecked;
                    toolStripButtonSketch.Checked = false;
                    MenuItemStop.CheckState = CheckState.Unchecked;
                    toolStripButtonStop.Checked = false;
                }
                else if (_drawtype == DrawType.Rect)
                {
                    MenuItemLine.CheckState = CheckState.Unchecked;
                    toolStripButtonLine.Checked = false;
                    MenuItemRect.CheckState = CheckState.Checked;
                    toolStripButtonRect.Checked = true;
                    MenuItemCircle.CheckState = CheckState.Unchecked;
                    toolStripButtonCircle.Checked = false;
                    MenuItemSketch.CheckState = CheckState.Unchecked;
                    toolStripButtonSketch.Checked = false;
                    MenuItemStop.CheckState = CheckState.Unchecked;
                    toolStripButtonStop.Checked = false;
                }
                else if (_drawtype == DrawType.Circle)
                {
                    MenuItemLine.CheckState = CheckState.Unchecked;
                    toolStripButtonLine.Checked = false;
                    MenuItemRect.CheckState = CheckState.Unchecked;
                    toolStripButtonRect.Checked = false;
                    MenuItemCircle.CheckState = CheckState.Checked;
                    toolStripButtonCircle.Checked = true;
                    MenuItemStop.CheckState = CheckState.Unchecked;
                    toolStripButtonStop.Checked = false;
                    MenuItemSketch.CheckState = CheckState.Unchecked;
                    toolStripButtonSketch.Checked = false;
                    MenuItemSketch.CheckState = CheckState.Unchecked;
                    toolStripButtonSketch.Checked = false;
                }
                else if (_drawtype == DrawType.Sketch)
                {
                    MenuItemLine.CheckState = CheckState.Unchecked;
                    toolStripButtonLine.Checked = false;
                    MenuItemRect.CheckState = CheckState.Unchecked;
                    toolStripButtonRect.Checked = false;
                    MenuItemCircle.CheckState = CheckState.Unchecked;
                    toolStripButtonCircle.Checked = false;
                    MenuItemStop.CheckState = CheckState.Unchecked;
                    toolStripButtonStop.Checked = false;
                    MenuItemSketch.CheckState = CheckState.Checked;
                    toolStripButtonSketch.Checked = true;
                }
                else if (_drawtype == DrawType.Stop)
                {
                    MenuItemLine.CheckState = CheckState.Unchecked;
                    toolStripButtonLine.Checked = false;
                    MenuItemRect.CheckState = CheckState.Unchecked;
                    toolStripButtonRect.Checked = false;
                    MenuItemCircle.CheckState = CheckState.Unchecked;
                    toolStripButtonCircle.Checked = false;
                    MenuItemSketch.CheckState = CheckState.Unchecked;
                    toolStripButtonSketch.Checked = false;
                    MenuItemStop.CheckState = CheckState.Checked;
                    toolStripButtonStop.Checked = true;
                }
            }
        }

        public Form1() 
        {
            InitializeComponent();
        }

 

        private void MenuItemLine_Click(object sender, EventArgs e)
        {
            _Drawtype = DrawType.Line;
            
        }

        private void MenuItemRect_Click(object sender, EventArgs e)
        {
            _Drawtype = DrawType.Rect;
            
        }

        private void MenuItemCircle_Click(object sender, EventArgs e)
        {
            _Drawtype = DrawType.Circle;
                  
        }

        private void MenuItemSketch_Click(object sender, EventArgs e)
        {
            _Drawtype = DrawType.Sketch;
        }    

        private void MenuItemStop_Click(object sender, EventArgs e)
        {
            _Drawtype = DrawType.Stop;
             
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //获取当前应用程序域的BufferedGraphicsContext对象，以利用双缓冲技术来减少或消除重绘显示图画时产生的闪烁
            _bufGraphCont = BufferedGraphicsManager.Current;
            //使用与this.CreateGraphics()相同的像素格式来创建指定大小的图形缓冲区
            _bufGraph = _bufGraphCont.Allocate(panelDraw.CreateGraphics(), panelDraw.ClientRectangle);
            //清空图形缓冲区
            _bufGraph.Graphics.Clear(Color.White);
            //设置抗锯齿平滑模式
            _bufGraph.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            _drawtype = DrawType.Line;
            _panelDrawInitSize.Width = panelDraw.Width;
            _panelDrawInitSize.Height = panelDraw.Height;
            MenuItemLine.CheckState = CheckState.Checked;
            toolStripButtonLine.Checked = true;
            //设置默认光标
            toolStrip1.Cursor = Cursors.Arrow;
            menuStrip1.Cursor = Cursors.Default;

            Cursor myCursor = new Cursor("pencil.cur");
            this.Cursor = myCursor;
        }

        private void MenuItemWidth_Click(object sender, EventArgs e)
        {
            //创建一个对话框类对象
            DlgPenWidth dlgPenWidth = new DlgPenWidth();
            //设置默认线宽
            dlgPenWidth.PenWidth1.Value = _drawWidth;
            //显示对话框
            if (dlgPenWidth.ShowDialog() == DialogResult.OK)
            {
                //保存用户设置的对话框
                _drawWidth = (int)dlgPenWidth.PenWidth1.Value;
            }
        }

        private void MenuItemColor_Click(object sender, EventArgs e)
        {
            //设置默认颜色
            colorDialog1.Color = _drawColor;
            if (colorDialog1.ShowDialog() == DialogResult.OK)
            {
                ToolStripMenuItemRed.Checked = false;
                ToolStripMenuItemYellow.Checked = false;
                ToolStripMenuItemBlue.Checked = false;
                ToolStripMenuItemBlack.Checked = false;
                ToolStripMenuItemGreen.Checked = false;
                _drawColor = colorDialog1.Color;
            }
            
            
        }

        private void MenuItemUndo_Click(object sender, EventArgs e)
        {
            //只有存在图元时才能撤销
            if (_listShape.Count > 0)
            {
                //删除前先把最后一个图元保存到_listDelShape
                _listDelShape.Add(_listShape[_listShape.Count - 1]);
                //去除最后一个节点
                
                _listShape.RemoveAt(_listShape.Count - 1);

                _bufGraph.Graphics.Clear(Color.White);
                foreach (Shape shape in _listShape)
                {
                    shape.Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation);
                }
                _bufGraph.Render(panelDraw.CreateGraphics());
                //使菜单变灰
                if (_listShape.Count == 0)
                {
                    MenuItemUndo.Enabled = false;
                    toolStripButtonUndo.Enabled = false;
                }
               
            }
            if (_listDelShape.Count > 0)
            {
                MenuItemRedo.Enabled = true;
                toolStripButtonRedo.Enabled = true;
            }

        }

        private void MenuItemRedo_Click(object sender, EventArgs e)
        {
            if (_listDelShape.Count > 0)
            {
                _listShape.Add(_listDelShape[_listDelShape.Count - 1]);
                _listDelShape.RemoveAt(_listDelShape.Count - 1);
                _bufGraph.Graphics.Clear(Color.White);
                foreach (Shape shape in _listShape)
                {
                    shape.Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation);
                }
                _bufGraph.Render(panelDraw.CreateGraphics());
                if (_listShape.Count != 0)
                {
                    MenuItemUndo.Enabled = true;
                    toolStripButtonUndo.Enabled = true;
                }
            }
            if (_listDelShape.Count == 0)
            {
                MenuItemRedo.Enabled = false;
                toolStripButtonRedo.Enabled = false;
            }
        }

        private void pxToolStripMenuItem2px_Click(object sender, EventArgs e)
        {
            _drawWidth = 2;
        }

        private void pxToolStripMenuItem1px_Click(object sender, EventArgs e)
        {
            _drawWidth = 1;
        }

        private void pxToolStripMenuItem10px_Click(object sender, EventArgs e)
        {
            _drawWidth = 10;
        }

        private void pxToolStripMenuItem20px_Click(object sender, EventArgs e)
        {
            _drawWidth = 20;
        }

        private void MenuItemNew_Click(object sender, EventArgs e)
        {
            _listShape.Clear();

            _bufGraph.Graphics.Clear(Color.White);
            foreach (Shape shape in _listShape)
            {
                shape.Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation);
            }
            _bufGraph.Render(panelDraw.CreateGraphics());
        }

        private void ToolStripMenuItemRed_Click(object sender, EventArgs e)
        {
            _drawColor = Color.Red;
            ToolStripMenuItemRed.Checked = true;
            ToolStripMenuItemYellow.Checked = false;
            ToolStripMenuItemBlue.Checked = false;
            ToolStripMenuItemGreen.Checked = false;
            ToolStripMenuItemBlack.Checked = false;
        }

        private void ToolStripMenuItemGreen_Click(object sender, EventArgs e)
        {
            _drawColor = Color.Green;
            ToolStripMenuItemRed.Checked = false;
            ToolStripMenuItemYellow.Checked = false;
            ToolStripMenuItemBlue.Checked = false;
            ToolStripMenuItemGreen.Checked = true;
            ToolStripMenuItemBlack.Checked = false;
        }

        private void ToolStripMenuItemYellow_Click(object sender, EventArgs e)
        {
            _drawColor = Color.Yellow;
            ToolStripMenuItemRed.Checked = false;
            ToolStripMenuItemYellow.Checked = true;
            ToolStripMenuItemBlue.Checked = false;
            ToolStripMenuItemGreen.Checked = false;
            ToolStripMenuItemBlack.Checked = false;
        }

        private void ToolStripMenuItemBlue_Click(object sender, EventArgs e)
        {
            _drawColor = Color.Blue;
            ToolStripMenuItemRed.Checked = false;
            ToolStripMenuItemYellow.Checked = false;
            ToolStripMenuItemBlue.Checked = true;
            ToolStripMenuItemGreen.Checked = false;
            ToolStripMenuItemBlack.Checked = false;
        }

        private void ToolStripMenuItemBlack_Click(object sender, EventArgs e)
        {
            _drawColor = Color.Black;
            ToolStripMenuItemRed.Checked = false ;
            ToolStripMenuItemYellow.Checked = false;
            ToolStripMenuItemBlue.Checked = false;
            ToolStripMenuItemGreen.Checked = false;
            ToolStripMenuItemBlack.Checked = true;
        }

        private void MenuItemSave_Click(object sender, EventArgs e)
        {
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                _fileName = saveFileDialog.FileName;
                FileStream fs = new FileStream(_fileName, FileMode.Create);
                BinaryWriter bw = new BinaryWriter(fs);
                //保存图元的总数
                bw.Write(_listShape.Count);
                //逐一保存所有图元
                foreach (Shape shape in _listShape)
                {
                    //保存图元类型
                    bw.Write(shape.GetType().ToString());
                    shape.Write(bw);
                }
                bw.Close();
                fs.Close();
            }
        }

        private void MenuItemOpen_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                MenuItemNew_Click(sender, e);
                _fileName = openFileDialog.FileName;
                FileStream fs = new FileStream(_fileName, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fs);
                int shapeCount = br.ReadInt32();

                for (int i = 0; i < shapeCount; i++)
                {
                    String ShapeType = br.ReadString();
                    if (ShapeType == "MyPen.Line")
                    {
                        Line shape = new Line();
                        shape.Read(br);
                        _listShape.Add(shape);
                    }
                    else if (ShapeType == "MyPen.Rect")
                    {
                        Rect shape = new Rect();
                        shape.Read(br);
                        _listShape.Add(shape);
                    }
                    else if (ShapeType == "MyPen.Circle")
                    {
                        Circle shape = new Circle();
                        shape.Read(br);
                        _listShape.Add(shape);
                    }
                    else if (ShapeType == "MyPen.Sketch")
                    {
                        Sketch shape = new Sketch();
                        shape.Read(br);
                        _listShape.Add(shape);
                    }
                    //else
                        //MessageBox.Show("图元类型错误。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                br.Close();
                fs.Close();
                _bufGraph.Graphics.Clear(Color.White);
                foreach (Shape shape in _listShape)
                    shape.Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation);
                _bufGraph.Render(panelDraw.CreateGraphics());

            }
            
        }

        private void panelDraw_MouseDown(object sender, MouseEventArgs e)
        {
            if (_drawtype != DrawType.Stop)
            {
                if (_drawtype == DrawType.Line)
                {
                    _tempShape = new Line();
                    ((Line)_tempShape).P1 = new Point((int)(e.X / _zoomRation), (int)(e.Y / _zoomRation));

                }
                else if (_drawtype == DrawType.Rect)
                {
                    _tempShape = new Rect();
                    ((Rect)_tempShape).P1 = new Point((int)(e.X / _zoomRation), (int)(e.Y / _zoomRation));
                }
                else if (_drawtype == DrawType.Circle)
                {
                    _tempShape = new Circle();
                    ((Circle)_tempShape).PCenter = new Point((int)(e.X / _zoomRation), (int)(e.Y / _zoomRation));
                }
                else if (_drawtype == DrawType.Sketch)
                {
                    _tempShape = new Sketch();
                    //保存鼠标下压点坐标（即第一个点）到_tempShape._PointList中
                    ((Sketch)_tempShape)._PointList.Add(new Point((int)(e.X / _zoomRation), (int)(e.Y / _zoomRation)));
                }
                _tempShape.PenColor = _drawColor;
                _tempShape.PenWidth = _drawWidth;
            }
        }

        private void MenuItemZoomIn_Click(object sender, EventArgs e)
        {
            _zoomRation *= 1.1;
            panelDraw.Width = (int)(_panelDrawInitSize.Width * _zoomRation);
            panelDraw.Height = (int)(_panelDrawInitSize.Height * _zoomRation);
            _bufGraph = _bufGraphCont.Allocate(panelDraw.CreateGraphics(), panelDraw.ClientRectangle);
            _bufGraph.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            _bufGraph.Graphics.Clear(Color.White);
            foreach (Shape shape in _listShape)
                shape.Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation);
            _bufGraph.Render(panelDraw.CreateGraphics());
        }

        private void MenuItemZoomOut_Click(object sender, EventArgs e)
        {
            _zoomRation *= 0.9;
            panelDraw.Width = (int)(_panelDrawInitSize.Width * _zoomRation);
            panelDraw.Height = (int)(_panelDrawInitSize.Height * _zoomRation);
            _bufGraph = _bufGraphCont.Allocate(panelDraw.CreateGraphics(), panelDraw.ClientRectangle);
            _bufGraph.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            _bufGraph.Graphics.Clear(Color.White);
            foreach (Shape shape in _listShape)
                shape.Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation);
            _bufGraph.Render(panelDraw.CreateGraphics());

        }

        private void panelDraw_Paint(object sender, PaintEventArgs e)
        {
            _bufGraph.Graphics.Clear(Color.White);
            for (int i = 0; i < _listShape.Count; i++)
                _listShape[i].Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation) ;
            _bufGraph.Render(e.Graphics);
        }

        private void panelDraw_MouseUp(object sender, MouseEventArgs e)
        {
            if (_drawtype != DrawType.Stop)
            {
                if (_drawtype == DrawType.Line)
                {
                    ((Line)_tempShape).P2 = new Point(e.X, e.Y);
                }
                else if (_drawtype == DrawType.Rect)
                {
                    ((Rect)_tempShape).P2 = new Point(e.X, e.Y);
                }
                else if (_drawtype == DrawType.Circle)
                {
                    ((Circle)_tempShape).R = (float)Math.Sqrt(Math.Pow((e.X - ((Circle)_tempShape).PCenter.X), 2) +
                                                            Math.Pow((e.Y - ((Circle)_tempShape).PCenter.Y), 2));
                }
                else if (_drawtype == DrawType.Sketch)
                    //保存鼠标抬起点坐标（末尾点）到_tempShape._PointList中
                    ((Sketch)_tempShape)._PointList.Add(e.Location);

                _listShape.Add(_tempShape);
                _tempShape.Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation);
                _bufGraph.Render(panelDraw.CreateGraphics());
            }
        }

        private void panelDraw_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (_drawtype != DrawType.Stop)
                {
                    _bufGraph.Graphics.Clear(Color.White);
                    foreach (Shape shape in _listShape)
                        shape.Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation);

                    if (_drawtype == DrawType.Line)
                    {
                        ((Line)_tempShape).P2 = e.Location;
                        toolStripStatusLabelMouse.Text = "当前位置为：x=" + e.X + ",y=" + e.Y + ",直线长度L=" + ((Line)_tempShape).Length;
                        _tempShape.Draw(_bufGraph.Graphics, DashStyle.Dash, _zoomRation);
                    }
                    else if (_drawtype == DrawType.Rect)
                    {
                        ((Rect)_tempShape).P2 = e.Location;
                        toolStripStatusLabelMouse.Text = "当前位置为：x=" + e.X + ",y=" + e.Y + ",矩形宽度=" + ((Rect)_tempShape)._Wid + ",矩形高度=" + ((Rect)_tempShape)._Hei;
                        _tempShape.Draw(_bufGraph.Graphics, DashStyle.Dash, _zoomRation);
                    }
                    else if (_drawtype == DrawType.Circle)
                    {
                        ((Circle)_tempShape).R = (float)Math.Sqrt(Math.Pow((e.X - ((Circle)_tempShape).PCenter.X), 2) +
                                                            Math.Pow((e.Y - ((Circle)_tempShape).PCenter.Y), 2));
                        _tempShape.Draw(_bufGraph.Graphics, DashStyle.Dash, _zoomRation);
                        toolStripStatusLabelMouse.Text = "当前位置为：x=" + e.X + ",y=" + e.Y + ",圆的半径=" + (int)((Circle)_tempShape).R;
                    
                    }
                    else if (_drawtype == DrawType.Sketch)
                    {
                        //保存鼠标下压点坐标（即第一个点）到_tempShape._PointList中
                        ((Sketch)_tempShape)._PointList.Add(e.Location);
                        _tempShape.Draw(_bufGraph.Graphics, DashStyle.Solid, _zoomRation);
                        toolStripStatusLabelMouse.Text = "当前位置为：x=" + e.X + ",y=" + e.Y;
                    }
                    _bufGraph.Render(panelDraw.CreateGraphics());
                }
            }
        }

            
    }
}
